package com.woniuxy.factories;



import com.woniuxy.person.Person;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Auther: ideaAdmin  <br/>
 * Date: 17:08:2022/1/17  <br/>
 * Description: 根据配置文件 可以选择是单例还是不是单例模式
 **/

public final class BeanFactoryCanChoose {

    //存储配置文件里面的所有对象
    private static Map<String, Object> beans = new ConcurrentHashMap<>();


    //静态代码块来读取配置文件并装入mao中
    static {
        initBeanFactory();
    }

    private static void initBeanFactory() {
        InputStream is = null;
        try {
            //获得配置文件所在的地方

            is = Class.forName("com.woniuxy.factories.BeanFactoryCanChoose").getResourceAsStream("personCanChoose.properties");

            //创建 Properties 读取配置文件
            Properties properties = new Properties();
            properties.load(is);

            //获得配置文件的所有key
            Set<String> strings = properties.stringPropertyNames();

            for (String str : strings) {
                //获得value 通过"," 来做分隔
                String[] split = properties.getProperty(str).split(",");

                //如果长度只有1 或者 标记属性为prototype 那么就是原型 表示不是单例
                if(split.length == 1 || (split[1].equals("prototype"))){
                    beans.put(str, split[0]);

                }else if(split[1].equals("singleton")){
                    //如果后缀为 singleton 表示是单例对象 可以在这里就实例化存入map
                    //获得单例的对象
                    beans.put(str, Class.forName(split[0]).newInstance());
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            if (is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }


    //通过类别名 来获得指定类的对象
    public Person getBean(String className) {
        Person person = null;

        //获得map里面存储的对象来做判断
        Object o = beans.get(className);

        //如果是String的字符串 那么说明他是原型 就是全限定名 需要在这实例化对象 并返回
        if(o instanceof  String){
            try {
                person = (Person) Class.forName((String) o).newInstance();
                return person;
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

        //说明是单例对象 直接转型后返回
        return (Person) beans.get(className);
    }

}
